import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '@/store'
import NProgress from 'nprogress'
import Layout from '@/layout/index'
import {getToken} from '@/utils/auth'
import db from '@/utils/localstorage'
import {getAuthorities} from '@/api/system/security'

Vue.use(VueRouter)
// 防止路由跳转报错
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
}

/**
 * 路由常量
 * @type {({path: string, component: (function(): Promise<*>), hidden: boolean, meta: {noCache: boolean, title: string}}|{path: string, component, hidden: boolean, children: [{path: string, component: function(): Promise<*>}]}|{redirect: string, path: string, component, children: [{path: string, component: function(): Promise<*>, meta: {noCache: boolean, affix: boolean, icon: string, title: string}, name: string}]}|{redirect: string, path: string, component, hidden: boolean, children: [{path: string, component: function(): Promise<*>, meta: {noCache: boolean, title: string}, name: string}]}|{path: string, component: (function(): Promise<*>), meta: {icon: string, title: string}, name: string})[]}
 */
export const constRouter = [
  {
    path: '/login',
    hidden: true,
    component: () => import('@/views/login'),
    meta: {title: '登陆', noCache: true}
  },
  {
    path: '/redirect',
    hidden: true,
    component: Layout,
    children: [
      {
        path: '/redirect/:path*',
        component: () => import('@/views/redirect')
      }
    ]
  },
  {
    path: '/',
    component: Layout,
    redirect: '/dashboard',
    children: [
      {
        path: 'dashboard',
        component: () => import('@/views/dashboard'),
        name: 'dashboard',
        meta: {title: '首页', icon: 'index', affix: true, noCache: true}
      }
    ]
  },
  {
    path: '/profile',
    hidden: true,
    component: Layout,
    redirect: '',
    children: [
      {
        path: '',
        name: 'profile',
        component: () => import('@/views/profile'),
        meta: {title: '个人资料', noCache: true}
      }
    ]
  },
  {
    path: '/404',
    name: '/404',
    component: () => import('@/views/features/404'),
    meta: {title: '404', icon: '404'}
  }
]

/**
 * 创建路由对象
 * @type {VueRouter}
 */
const router = new VueRouter({
  model: 'history',
  scrollBehavior: () => ({y: 0}),
  routes: constRouter
})

/**
 * 白名单
 * @type {string[]}
 */
const whiteList = ['/login']

/**
 * 异步路由
 */
let asyncRouter

/**
 * 路由前置卫士
 */
router.beforeEach((to, from, next) => {
  // console.log('进入导航卫士: ' + to.path)
  // 开启进度条
  NProgress.start()
  // 判断是否登陆
  if (getToken()) {
    // 判断是否拉取用户菜单及权限
    let userRouters = db.getByKey('USER_ROUTERS')
    // let permissions = db.getByKey('USER_PERMISSIONS')
    if (!asyncRouter) {
      if (!userRouters || userRouters.length === 0) {
        // 获取安全数据
        getAuthorities().then(response => {
          let routers = []
          let permissions = []
          if (response.data.routers) {
            routers = response.data.routers
            store.commit('user/setRouters', routers)
          }

          if (response.data.permissions) {
            permissions = response.data.permissions
            store.commit('user/setPermissions', permissions)
          }
          asyncRouter = routers
          go(to, next)
        })
      } else {
        asyncRouter = userRouters
        go(to, next)
      }
    } else {
      next()
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      next('/login')
    }
  }
})

/**
 * 路由后置钩子
 */
router.afterEach(() => {
  // 关闭进度条
  NProgress.done()
})

/**
 * 执行添加路由
 * @param to
 * @param next
 */
function go(to, next) {
  asyncRouter = filterAsyncRouter(asyncRouter)
  router.addRoutes(asyncRouter)
  next({...to, replace: true})
}

/**
 * 过滤异步路由
 * @param routers
 * @returns {*}
 */
function filterAsyncRouter(routers) {
  return routers.filter((router) => {
    const component = router.component
    if (component) {
      if (router.component === 'Layout') {
        router.component = Layout
      } else {
        router.component = view(component)
      }
      if (router.children && router.children.length) {
        router.children = filterAsyncRouter(router.children)
      }
      return true
    }
  })
}

/**
 * 生成视图
 * @param path
 * @returns {function(*=): *}
 */
function view(path) {
  return (resolve) => require([`@/views/${path}.vue`], resolve)
}

export default router
